%options automatic_ast=nested,ast_type=ASTNode,parent_saved
%options template=btParserTemplateF.gi
%options import_terminals=snooperLexer.gi
%options la=6

%Globals
    /.
    import 'Scope.dart';
    import 'Symbol.dart';
    import 'dart:typed_data';
    ./
%End

%Define
    $ast_class /.IAst./

%End

%Terminals
    --            
    -- Here, list aliases for terminals whose names are themselves
    -- not a valid IDENTIFIER in the parser's implementation language.
    DollarSign   ::= '$'
    MINUS_MINUS                ::= '--'
    OR                         ::= '|' 
    MINUS                      ::= -
    MINUS_EQUAL                ::= -=
    NOT                        ::= !
    NOT_EQUAL                  ::= !=
    REMAINDER                  ::= '%'
    REMAINDER_EQUAL            ::= '%='
    AND                        ::= &
    AND_AND                    ::= && 
    AND_EQUAL                  ::= &= 
    LPAREN                     ::= (
    RPAREN                     ::= )
    MULTIPLY                   ::= *
    MULTIPLY_EQUAL             ::= *=
    COMMA                      ::= ,
    DOT                        ::= .
    DIVIDE                     ::= / 
    DIVIDE_EQUAL               ::= /= 
    COLON                      ::= :
    SEMICOLON                  ::= ;
    QUESTION                   ::= ?
    AT                         ::= @  
    LBRACKET                   ::= '['
    RBRACKET                   ::= ']'
    XOR                        ::= ^ 
    XOR_EQUAL                  ::= ^=
    LBRACE                     ::= {
    OR_OR                      ::= || 
    OR_EQUAL                   ::= |=  
    RBRACE                     ::= }  
    TWIDDLE                    ::= ~  
    PLUS                       ::= + 
    PLUS_PLUS                  ::= ++
    PLUS_EQUAL                 ::= +=
    LESS                       ::= <  
    LEFT_SHIFT                 ::= << 
    LESS_EQUAL                 ::= <=
    EQUAL                      ::= =  
    EQUAL_EQUAL                ::= ==  
    GREATER                    ::= >
    GREATER_EQUAL              ::= >=
    RIGHT_SHIFT                ::= >>
 
  
%End

%Start
    SnooperProg
%End

%Recover
   MissingExpression
%End

%Rules

    SnooperProg ::= %empty 

    SnooperProg$SnooperProg ::= SnooperSegments
    /.
            Scope? scope;
            FunctionSymbol? sym;
    ./ 

    SnooperSegments$$SnooperSegmentItem  ::= SnooperSegmentItem | SnooperSegments SnooperSegmentItem 
   
         

    SnooperSegmentItem ::=  Statement
    SnooperSegmentItem ::=  FunctionDecl

    ReturnStmt ::= return ExpressionOpt  CRLF 

    SimpleNameOpt ::= %empty | SimpleName

    SimpleName ::= IDENTIFIER
    
    FunctionParameterList$$SimpleName ::= SimpleName | FunctionParameterList , SimpleName

    FunctionParameterListOpt ::= %empty | FunctionParameterList

    CallSignature ::=  ( FunctionParameterListOpt )
    CallSignatureOpt ::= %empty | CallSignature

    FunctionDecl ::= IDENTIFIER  CallSignatureOpt : CRLF BlockOpt ReturnStmt
    /.
            Scope? scope;
            FunctionSymbol? sym;
            String name(){
                return getIDENTIFIER().toString();
            }
    ./    
                                    
    StatementList$$Statement ::= Statement
                | StatementList Statement
    /.
            Scope? scope2;

    ./   

    Statement ::= StatementWithoutTrailingSubstatement
                | IfThenStatement
                | IfThenElseStatement

                | DoLoopStmt
                | ForStmt
                | HforStmt
                

    StatementWithoutTrailingSubstatement ::=   
                  ExitStatement 
                | VariableStmt
                | ExpressionStmt
               
                | LoadScriptStmt 
                | KeyWordWithoutParameterStmt
                | SleepStmt 
                | SetStmt
                | PrintStmt
                | AutoResponseStmt
                | WriteFifoStmt
                | UploadStmt
                | ResetStmt
                | InstallStmt
                | JcopAuthStmt
                | SelectStmt
                | DeleteStmt
                | Apdu2Stmt
                | PromptStmt 
                | ShowapduStmt
                | Des_3des_mac_Stmt
                | Full_3des_mac_Stmt
                | Mac_auto_mac_Stmt
                | SuperlongStmt
                | CompareStmt
                | Socket_messageStmt
                | GenerateStmt
                | SendtextStmt
                | PushStmt
                | GotoStmt
                | EmptyStatement

    IfSeg ::= if  Expression CRLF BlockOpt
    IfThenStatement ::= IfSeg  ElseIfStatementOpt endif CRLF

    ElseSeg ::= else  CRLF BlockOpt
    IfThenElseStatement ::=  IfSeg ElseIfStatementOpt  ElseSeg  endif  CRLF

    ElseIfStatementOpt  ::=  %empty | ElseIfStatementList

    ElseIfStatementList$$ElseIfStatementItem ::=  ElseIfStatementItem | ElseIfStatementList  ElseIfStatementItem

    ElseIfStatementItem ::= else if Expression CRLF BlockOpt  

    EmptyStatement ::= CRLF | ;


    Variable$Variable ::= MACRO_IDENTIFIER 
    /.
            VarSymbol? sym;
    ./ 

    Variable$BadVariable ::=  DollarSign IDENTIFIER
    /.
            VarSymbol? sym;
    ./ 
    BlockOpt ::= %empty |  StatementList

    LetOpt ::= %empty | let

    VariableStmt ::= LetOpt VariableDecl CRLF

    PrimaryAssignmentStmt ::=  IDENTIFIER = Expression  
    /.
            Scope? scope;
    ./ 

    VariableDecl ::= PrimaryAssignmentStmt  

    
    ArrayAccesOnLeftSide ::= IDENTIFIER '[' Expression ']'

    ArrayAccessAssignmentStmt ::=  ArrayAccesOnLeftSide = Expression 
    /.
            VarSymbol? sym;
    ./ 
    VariableDecl ::= ArrayAccessAssignmentStmt

    VariableDecl$KeywordAssignmentStmt ::= sw = Expression  
    /.
             VarSymbol? sym;
    ./ 
    VariableDecl$BadAssignment ::=  IDENTIFIER =
    /.
            VarSymbol? sym;
    ./ 

    DoLoopStmt ::= do  ExpressionOpt CRLF BlockOpt loop 
    /.
            Scope? scope;
    ./ 
  
    StepStmOpt ::= %empty | step Expression

    NextSegItem ::= NumberLiteral | SimpleName

    ForStmt ::= for VariableDecl to Primary StepStmOpt CRLF BlockOpt  NextSeg 
    /.
            Scope? scope;
    ./ 
    NextSeg ::= next  NextSegItem CRLF
    

    HforStmt ::= hfor VariableDecl to Primary StepStmOpt  CRLF BlockOpt  HnexSeg 
    /.
            Scope? scope;
    ./ 

    HnexSeg ::= hnext  NextSegItem CRLF


    NumberLiteral ::= NUMBER
    /.
            Uint8List? value;
    ./

    StringLiteral ::= STRING_LITERAL
    /.
            Uint8List? value;
    ./

    ArrayAccess ::= Variable '[' Expression ']'

    Primary ::=  HexMacroAbleItem 

    Primary$HexMacroPrimary ::= HEX_MACRO_PREFIX HexMacroAbleItem

    Primary ::= FunctionCall

    Primary ::= StringLiteral


    HexMacroAbleItem ::=  VariableAndSW | NumberLiteral |  ArrayAccess      
      
    ApduData$ApduDataWith3Lc ::= { ApduDataList }

    ApduData$ApduDataWith2Lc ::= ( ApduDataList )

    ApduData$ApduDataWith4Lc ::= < ApduDataList >

    ApduData$ApduDataWithoutLc ::= Primary
  

    ApduDataList$$ApduData ::= ApduData | ApduDataList ApduData

    PostfixExpression ::= ApduDataList
                        | PostIncrementExpression
                        | PostDecrementExpression
    
    PostIncrementExpression ::= PostfixExpression ++
    
    PostDecrementExpression ::= PostfixExpression '--'
    
    UnaryExpression ::= PreIncrementExpression
                      | PreDecrementExpression
                      | UnaryExpressionNotPlusMinus
    
    PreIncrementExpression ::= ++ UnaryExpression
    
    PreDecrementExpression ::= '--' UnaryExpression
    
    UnaryExpressionNotPlusMinus ::= PostfixExpression
    UnaryExpressionNotPlusMinus$UnaryExpNotPlusMinus_Xor ::= ~ UnaryExpression
    UnaryExpressionNotPlusMinus$UnaryExpNotPlusMinus_Not ::= ! UnaryExpression
                                 

    MultiplicativeExpression ::= UnaryExpression
    MultiplicativeExpression$MultiplicativeExp_Divide ::=  MultiplicativeExpression * UnaryExpression
    MultiplicativeExpression$MultiplicativeExp_Multiply ::=  MultiplicativeExpression / UnaryExpression
    MultiplicativeExpression$MultiplicativeExp_Remainder ::=  MultiplicativeExpression '%' UnaryExpression
    
    AdditiveExpression ::= MultiplicativeExpression
    AdditiveExpression$AdditiveExp_Plus ::= AdditiveExpression + MultiplicativeExpression
    AdditiveExpression$AdditiveExp_Minus ::= AdditiveExpression - MultiplicativeExpression
    
    ShiftExpression ::= AdditiveExpression
    ShiftExpression$ShiftExp_Left ::=  ShiftExpression << AdditiveExpression
    ShiftExpression$ShiftExp_Right ::=  ShiftExpression >> AdditiveExpression

    RelationalExpression ::= ShiftExpression
    RelationalExpression$RelationalExp_Less ::=  RelationalExpression < ShiftExpression
    RelationalExpression$RelationalExp_Greater ::=  RelationalExpression > ShiftExpression
    RelationalExpression$RelationalExp_LessEqual ::=  RelationalExpression <= ShiftExpression
    RelationalExpression$RelationalExp_GreaterEqual ::=  RelationalExpression >= ShiftExpression

    
    EqualityExpression ::= RelationalExpression
    EqualityExpression$EqualityExpr_EqualEqual ::= EqualityExpression == RelationalExpression
    EqualityExpression$EqualityExpr_NotEqual ::= EqualityExpression != RelationalExpression
    
    AndExpression ::= EqualityExpression
                    | AndExpression & EqualityExpression
    
    ExclusiveOrExpression ::= AndExpression
                            | ExclusiveOrExpression ^ AndExpression
    
    InclusiveOrExpression ::= ExclusiveOrExpression
                            | InclusiveOrExpression '|' ExclusiveOrExpression
    
    ConditionalAndExpression ::= InclusiveOrExpression
                               | ConditionalAndExpression && InclusiveOrExpression
    
    ConditionalOrExpression ::= ConditionalAndExpression
                              | ConditionalOrExpression || ConditionalAndExpression
    

    Expression ::= ConditionalOrExpression

    ExpressionStmt ::= Expression CRLF

    ExpressionOpt ::= %empty | Expression


    VariableAndSW ::= sw 
    /.
            VarSymbol? sym;
    ./ 
    VariableAndSW ::=  Variable

    ArgumentList$$Expression ::= Expression | ArgumentList , Expression

    ArgumentListOpt ::= %empty | ArgumentList

    CallOpt ::= %empty | call

    FunctionCall ::=  CallOpt IDENTIFIER ( ArgumentListOpt )
    /.
            FunctionSymbol? sym;
    ./ 

    FunctionCall ::= Des_3des_mac_call 
    FunctionCall ::= Full_3des_mac_call


    ExitStatement$ExitForStatement ::= exit for CRLF 
    
    ExitStatement$ExitHforStatement ::= exit hfor CRLF



    LoadOption$LoadOption_load_script ::= load_script 

    LoadOption$LoadOption_loadprofile ::= loadprofile 

    LoadOption$LoadOption_run_script ::= run_script

    LoadScriptStmt ::=  LoadOption STRING_LITERAL CRLF
                      
    SimpleOption$SimpleOption_timer_begin ::=  timer_begin 
    SimpleOption$SimpleOption_timer_end ::=  timer_end 
    SimpleOption$SimpleOption_pause ::=  pause 
    SimpleOption$SimpleOption_file ::=  __file__ 
    SimpleOption$SimpleOption_line ::=  __line__
    SimpleOption$SimpleOption_clear_fifo ::=  clear_fifo 
    SimpleOption$SimpleOption_beep ::=  beep 
    SimpleOption$SimpleOption_eject ::=  eject 
    SimpleOption$SimpleOption_insert ::=  insert 
    SimpleOption$SimpleOption_split ::=  split 
    SimpleOption$SimpleOption_end ::=   end
    SimpleOption$SimpleOption_clear ::=  clear

    KeyWordWithoutParameterStmt  ::= SimpleOption CRLF

    
    SleepStmt ::= sleep Expression CRLF

    SetStmt$SetStmt_Identifier ::= set IDENTIFIER  CRLF 

    SetStmt$SetStmt_MacroName ::= set Variable CRLF

    PrintStmt$PrintStmt_Message ::= message ExpressionOpt CRLF 

    PrintStmt$PrintStmt_Quqstion ::= ? ExpressionOpt CRLF

    OnOffOption$OnOffOption_on ::= on 

    OnOffOption$OnOffOption_off ::=  off 

    AutoResponseStmt ::=  auto_response OnOffOption CRLF

    WriteFifoStmt$WriteFifoStmt_Identifier ::= write_fifo IDENTIFIER  CRLF 

    WriteFifoStmt$WriteFifoStmt_MacroName ::= write_fifo Variable CRLF

    UploadStmt$UploadStmt_upload ::=   upload STRING_LITERAL CRLF

    UploadStmt$UploadStmt_upload2 ::=   upload2 STRING_LITERAL CRLF

    ResetStmt$ResetStmt_reset ::= reset CRLF

    ResetStmt$ResetStmt_reset2 ::= reset2 CRLF

    ResetStmt$ResetStmt_reset_cold ::= reset cold CRLF

    ResetStmt$ResetStmt_reset2_cold ::= reset2 cold CRLF
 
    InstallParameter ::= PrimaryAssignmentStmt | ParameterItem
    InstallParameterList$$InstallParameter ::= InstallParameter
                                            | InstallParameterList , InstallParameter

    InstallStmt$InstallStmt_install ::=  install InstallParameterList  CRLF

    InstallStmt$InstallStmt_install_2 ::=  install_2 InstallParameterList  CRLF

    ParameterItem ::=   IDENTIFIER | VariableAndSW | NumberLiteral |  StringLiteral

    UtilFunctionParameterList$$ParameterItem ::=  ParameterItem | UtilFunctionParameterList , ParameterItem

    JcopAuthStmt$JcopAuthStmt_jcop22_ext_auth ::= jcop22_ext_auth UtilFunctionParameterList CRLF

    JcopAuthStmt$JcopAuthStmt_jcop22_ext_auth_kmc ::= jcop22_ext_auth_kmc UtilFunctionParameterList CRLF

    JcopAuthStmt$JcopAuthStmt_jcop22_ext_auth_2 ::= jcop22_ext_auth_2 UtilFunctionParameterList CRLF

    JcopAuthStmt$JcopAuthStmt_jcop22_ext_auth_kmc_2 ::= jcop22_ext_auth_kmc_2 UtilFunctionParameterList CRLF

    JcopAuthStmt$JcopAuthStmt_jcop22_ext_auth_nonblock ::= jcop22_ext_auth_nonblock UtilFunctionParameterList CRLF

  
    SelectStmt$SelectStmt_select  ::=  select  IDENTIFIER UtilFunctionParameterList  CRLF

    SelectStmt$SelectStmt_select_2  ::=  select_2  IDENTIFIER UtilFunctionParameterList  CRLF


    DeleteStmt$DeleteStmt_delete ::=  delete  UtilFunctionParameterList  CRLF

    DeleteStmt$DeleteStmt_delete_2 ::=  delete_2  UtilFunctionParameterList  CRLF

    Apdu2Stmt ::= apdu2  ApduDataList CRLF

    PromptStmt ::= prompt OnOffOption CRLF

    ShowapduStmt ::= showapdu OnOffOption CRLF

    Des_3des_mac_call ::=  des_3des_mac ( ArgumentList ) 
    Des_3des_mac_Stmt ::=  des_3des_mac ApduDataList  CRLF

    Full_3des_mac_call ::=  full_3des_mac ( ArgumentList ) 
    Full_3des_mac_Stmt ::=  full_3des_mac ApduDataList  CRLF    


    Mac_auto_mac_option$Mac_auto_mac_option ::=  mac_auto_mac
    Mac_auto_mac_option$Mac_auto_mac_option2 ::=   mac_auto_mac_2

    Mac_auto_mac_Stmt  ::=   Mac_auto_mac_option ApduDataList CRLF

    LineEndOpt ::= %empty |  CRLF

    SuperlongStmt$SuperlongStmtInOneLine ::= superlong { LineEndOpt ApduDataList }  CRLF
 
    MultipleLineApduDataList$$ApduData ::= ApduData CRLF | MultipleLineApduDataList ApduData CRLF
    SuperlongStmt$SuperlongStmtInMutipleLines ::= superlong { LineEndOpt MultipleLineApduDataList }  CRLF


    CompareStmt ::= compare UtilFunctionParameterList CRLF

    Socket_messageStmt ::= socket_message   UtilFunctionParameterList CRLF

    GenerateStmt ::= generate  IDENTIFIER  UtilFunctionParameterList CRLF

    SendtextStmt ::= sendtext  Expression CRLF

    PushStmt  ::= push  ApduDataList  CRLF

    GotoStmt ::= goto IDENTIFIER CRLF 

 
%End

%Headers
    /.
    
    ./
%End
